package com.jysz.certificate.web.action.cm;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.jysz.certificate.action.AbstractBaseAction;
import com.jysz.certificate.persistence.enums.AttachmentType;
import com.jysz.certificate.persistence.enums.CertificateRenewState;
import com.jysz.certificate.persistence.enums.CertificationType;
import com.jysz.certificate.persistence.enums.WorkflowOperateType;
import com.jysz.certificate.persistence.enums.WorkflowType;
import com.jysz.certificate.persistence.model.cm.CertificateRenew;
import com.jysz.certificate.persistence.model.cm.Certification;
import com.jysz.certificate.persistence.model.cm.RenewObject;
import com.jysz.certificate.persistence.model.core.Attachment;
import com.jysz.certificate.persistence.model.system.Brand;
import com.jysz.certificate.persistence.model.system.Financial;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.persistence.model.workflow.Workflow;
import com.jysz.certificate.service.cm.CertificateRenewService;
import com.jysz.certificate.service.cm.CertificationService;
import com.jysz.certificate.service.core.AttachmentService;
import com.jysz.certificate.service.generator.SeqGenerator;
import com.jysz.certificate.service.system.BrandService;
import com.jysz.certificate.service.system.FinancialService;
import com.jysz.certificate.service.system.ShopService;
import com.jysz.certificate.service.workflow.WorkflowService;
import com.jysz.certificate.utils.CommonUtil;
import com.jysz.certificate.utils.DateUtil;
import com.jysz.webcore.utils.SshBeanUtils;

/**
 * 合格证换证
 * 
 * @author <a href="mailto:javaengine@outlook.com">Kaca Rich</a>
 *
 */
@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Namespace("/cm/renew")
public class CertificateRenewAction extends AbstractBaseAction {

	private static final long serialVersionUID = 1L;

	private final static Logger LOG = LoggerFactory.getLogger(CertificateRenewAction.class);
	private static final String SUBMIT="checkin";
	private static final String SAVE="save";
	private String operate;//操作 保存or提交
	
	@Resource
	private CertificateRenewService certificateRenewService;
	@Resource
	private FinancialService financialService;
	@Resource
	private BrandService brandService;
	@Resource 
	private ShopService shopService;
	@Resource
	private WorkflowService workflowService;// 流程
	@Resource
	private AttachmentService attachmentService;
	@Resource
	private SeqGenerator seqGenerator;
	@Resource
	private CertificationService certificationService;
	
	private CertificateRenew search;
	private CertificateRenew entity;
	private Workflow workflow;//释放单关联的流程
	private Integer state; //状态 用于查询
	private String ids;//合格证ids
	private String names;//车架号name
	
	private File file;
	private String fileFileName;//文件名称 
	private String fileContentType;	//文件类型  
	private List<Attachment> attachs;//附件
	
	private List<Brand> brands;//主机厂
	private List<Financial> financials;//金融机构
	
	private Integer flag;//是否来自流程列表
	
	private String auditMsg;//审核意见
	private String msg;
	
	private List<Shop> shops;
	
	@Action(INDEX)
	public String index() {
		if(state != null && state >= 0){
			if(search == null)
				search = new CertificateRenew();
			search.setState(CertificateRenewState.index(state)) ;
		}
		this.setPage(certificateRenewService.findPage(search, this.getCurrentPage(), this.getPageSize()));
		financials = financialService.finList();
		return INDEX;
	}
	
	@Action(ADD)
	public String add(){
		if(entity == null){
			entity = new CertificateRenew();
		}
		if(this.isShoper() ){
			shops = this.getCurrentUserShops();
			if(shops != null && shops.size() == 1){
				entity.setShop(shops.get(0));
				
				financials = financialService.findByShop(entity.getShop().getId());
				brands = entity.getShop().getBrands() != null ? new ArrayList<Brand>(entity.getShop().getBrands()) : new ArrayList<Brand>();
				
				if(entity.getShop().getDefaultBrand() != null){
					entity.setBrand(entity.getShop().getDefaultBrand());
				}
			}else if(shops != null && shops.size() > 0){
				financials = financialService.findAll();
				brands = brandService.findAll();
			}
		}else{
			financials = financialService.findAll();
			brands = brandService.findAll();
		}
	
		//TODO:合格释放新增选择，取当前用户所在店铺所关联的金融机构，和渠道，渠道选择，默认选择默认渠道。。
		entity.setApplyUser(super.getUser());
		
		return ADD;
	}
	
	/**
	 * 根据选择的ids构建换出合格证
	 */
	private void buildOutCf(){
		double supplyPrice = 0;
		if( CommonUtil.isNotEmpty(ids) ){
			String ary[] = ids.split(",");
			if(ary != null && ary.length > 0){
				Certification cf = null;
				Set<Certification> l = new HashSet<Certification>();
				for( String id: ary ){
					if( CommonUtil.isNotEmpty(id) ){
						cf = certificationService.find(Long.parseLong(id));
			
						if( cf != null ){
							if(cf.getSupplyPrice() <= 0){
								LOG.error("存在供货价为0合格证");
//								throw new WebSystemException("存在供货价为0合格证");
							}
							
							supplyPrice += cf.getSupplyPrice();
//							cf.setCertificateRenew(entity);

							l.add(cf);
						}
						
					}
					
				}
				entity.setOutCertifications(l);
				entity.setSupplyPrice(supplyPrice);
			}
		}
		
		
	}
	@Action(CREATE)
	public String create(){
		entity.setApplyDate(new Date());
		entity.setMsg(msg);
		buildOutCf();
		if(entity.getBrand() == null || entity.getBrand().getId() == null || entity.getBrand().getId() == 0){
			entity.setBrand(null);
		}
		
		if(SAVE.equals(operate)){//保存-未开始
			entity.setState(CertificateRenewState.NOSTART);
			certificateRenewService.save(super.getUser(), entity, file, fileFileName);
			setRedirectUrl("edit.do?entity.id=" + entity.getId());
		}else if(SUBMIT.equals(operate)){//提交-已提交
			Set<Certification> certifications = entity.getOutCertifications();
			if(this.validatorOutCertifications(certifications)){
				
				return this.add();
			}
//			else if(entity.getInSupplyPrice() < entity.getSupplyPrice()){
//				this.addActionError("入库供货价:" + entity.getInSupplyPrice() + "小于出库供货价:" + entity.getSupplyPrice());
//				
//				return this.add();
//			}
			
			Shop shop = shopService.find(entity.getShop().getId());
			entity.setApplyDate(new Date());
			entity.setApplyNum(shop.getShopMark() + "_" + DateUtil.formatDate(new Date(),"yyyy" +
					"MMdd") + "_" + seqGenerator.generateNextSeqNumber(CertificateRenew.class.getName()));
			
			//店员提交状态为提交
			//监管科 直接为已通过
//			if((PostType.Shop.equals(super.getUser().getPost()))){
				entity.setState(CertificateRenewState.SUBMITED);
//			}else{
//				entity.setState(CertificateRenewState.PASSED);
//			}
			
			certificateRenewService.saveAndSubmit(super.getUser(), entity, file, fileFileName,msg);
		}
		
		setSuccessPopMessage("新增数据成功");
		return SHOW_MSG_PAGE;
	}


	@Action(EDIT)
	public String edit(){
		if(entity != null && entity.getId() != null){
			entity = certificateRenewService.find(entity.getId());
			attachs = attachmentService.findAll(entity.getId(), AttachmentType.RENEW);
			setWorkflow();
		}
		
		String str="";
		if(state != null && state >= 0){
			str = "&state=" + state;
		}
		
		if(this.isShoper() ){
			shops = this.getCurrentUserShops();
		}
		financials = financialService.findByShop(entity.getShop().getId());
		brands = entity.getShop().getBrands() != null ? new ArrayList<Brand>(entity.getShop().getBrands()) : new ArrayList<Brand>();
		buildIds();//车架号-用于页面显示
		
		setRedirectUrl("index.do?currentPage="+getCurrentPage() + str,"search",search);
		
		return EDIT;
	}
	
	@Action("view")
	public String view(){
		if(entity != null && entity.getId() != null){
			entity = certificateRenewService.find(entity.getId());
			attachs = attachmentService.findAll(entity.getId(), AttachmentType.RENEW);
			setWorkflow();
		}
		
		financials = financialService.findAll();
		brands = brandService.findAll();
		buildIds();//车架号-用于页面显示
		
		return "view";
	}
	private void buildIds(){
		if(entity != null){
			StringBuilder sbId = new StringBuilder();
			StringBuilder sbName = new StringBuilder();
			for(Certification cf : entity.getOutCertifications()){
					sbId.append(cf.getId()).append(",");
					sbName.append(cf.getChassis()).append(",");
			}
			this.ids = sbId.toString();
			this.names = sbName.toString();
		}
	}
	private void setWorkflow(){
		workflow = workflowService.find(WorkflowType.RENEW, entity.getId());
	}
	
	@Action(UPDATE)
	public String update(){
		this.buildOutCf();
		CertificateRenew certificateRenew = certificateRenewService.find(entity.getId());
		String[] properties = {"financial","shop", "brand", "applyUser", "state", "outCertifications", "supplyPrice"};
		SshBeanUtils.copyProperties(entity, certificateRenew, properties);
		
		if(entity.getBrand() == null || entity.getBrand().getId() == null || entity.getBrand().getId() == 0){
			certificateRenew.setBrand(null);
		}
		
		certificateRenewService.syncInCf(certificateRenew);
		
		if(SAVE.equals(operate)){//保存-未开始
			certificateRenewService.save(super.getUser(), certificateRenew, file, fileFileName);
		}else if(SUBMIT.equals(operate)){
			if(this.validatorOutCertifications(certificateRenew.getOutCertifications()) || this.validatorInCertifications(certificateRenew.getInCertificateRenews())){
				return this.edit();
			}
			
//			else if(certificateRenew.getInSupplyPrice() < certificateRenew.getSupplyPrice()){
//				this.addActionError("入库供货价:" + certificateRenew.getInSupplyPrice() + "小于出库供货价:" + certificateRenew.getSupplyPrice());
//				
//				return this.edit();
//			}
//			
			Shop shop = shopService.find(certificateRenew.getShop().getId());
			certificateRenew.setApplyDate(new Date());
			certificateRenew.setApplyNum(shop.getShopMark() + "_" + DateUtil.formatDate(new Date(),"yyyyMMdd") + "_" + seqGenerator.generateNextSeqNumber(CertificateRenew.class.getName()));
			
			//店员提交状态为提交
			//监管科 直接为已通过
//			if(super.getUser().getPost() == PostType.Shop){
				certificateRenew.setState(CertificateRenewState.SUBMITED);
//			}else{
//				certificateRenew.setState(CertificateRenewState.PASSED);
//			}
			
			certificateRenewService.saveAndSubmit(super.getUser(), certificateRenew, file, fileFileName,msg);
		}
		setSuccessPopMessage("更新数据成功");
//		setRedirectUrl("index.do?currentPage="+getCurrentPage());
		return SHOW_MSG_PAGE;
	}
	
	private boolean validatorInCertifications(
			List<RenewObject> inCertificateRenews) {
		if(inCertificateRenews == null || inCertificateRenews.isEmpty()){
			this.addActionError("换入合格证数量为零,请检查后提交。");
			return true;
		}
		
		boolean b = false;
		for (Iterator<RenewObject> iterator = inCertificateRenews.iterator(); iterator.hasNext();) {
			RenewObject renewObject = iterator.next();
			
			if(renewObject.getBrand() == null){
				this.addActionError("合格证\"" + renewObject.getCertificationNum() + "\"未设置渠道,请设置后提交。");
				b = true;
			}
			
		}
		return b;
	}

	private boolean validatorOutCertifications(Set<Certification> certifications) {
		boolean b = false;
		
		if(certifications == null || certifications.isEmpty()){
			this.addActionError("换出合格证数量为零,请检查后提交。");
			return true;
		}
		
		for (Iterator<Certification> iterator = certifications.iterator(); iterator.hasNext();) {
			Certification certification = iterator.next();
			
			if((!CertificationType.RENEWPASS.equals(certification.getState())) && (!CertificationType.INSTOCK.equals(certification.getState()))){
				this.addActionError("合格证\"" + certification.getCertificationNum() + "\"未在库存。");
				b = true;
			}
			
			if(certification.getSupplyPrice() <= 0){
				this.addActionError("合格证\"" + certification.getCertificationNum() + "\"供货价小于0,不允许换出。");
			}
			
		}
		return b;
	}
	
	@Action(DESTORY)
	public String destory(){
		if(entity == null||entity.getId() == null){
			setSuccessPopMessage("缺少必要参数ID,请重新尝试");
			setRedirectUrl("index.do?currentPage=" + getCurrentPage());
			return SHOW_MSG_PAGE;
		}
		
		certificateRenewService.destory(entity.getId());
		setSuccessPopMessage("删除数据成功");
		setRedirectUrl("index.do?currentPage=" + getCurrentPage());
		return SHOW_MSG_PAGE;
	}
	
	@Action("preAudit")
	public String preAudit(){
		if(entity == null || entity.getId() == null){
			setSuccessPopMessage("缺少必要参数ID,请重新尝试");
			
			return SHOW_MSG_PAGE;
		}
		entity = certificateRenewService.find(entity.getId());
		attachs = attachmentService.findAll(entity.getId(), AttachmentType.RENEW);
		
		if(StringUtils.isBlank(this.getRedirectUrl())){
			if(flag != null && flag == 1){
				setRedirectUrl(getContextPath() + "/workflow/index.do?currentPage=" + getCurrentPage(), "search", search);
			}else{
				setRedirectUrl("index.do?currentPage=" + getCurrentPage(), "search", search);
			}
		}
		workflow = workflowService.find(WorkflowType.RENEW, entity.getId());
		return "audit";
	}
	
	@Action("audit")
	public String audit(){
		CertificateRenew certificateRenew = certificateRenewService.find(entity.getId());
		if(this.validatorOutCertifications(certificateRenew.getOutCertifications()) || this.validatorInCertifications(certificateRenew.getInCertificateRenews())){
			return preAudit();
		}
		
		WorkflowOperateType ot = null;
		if("pass".equals(operate)){
			ot = WorkflowOperateType.PASS;
			setSuccessPopMessage("审核通过");
		}else{
			ot = WorkflowOperateType.REFUSE;
			setSuccessPopMessage("审核不通过");
		}
			
		certificateRenewService.audit(super.getUser(), entity.getId(), auditMsg, ot);
		if(file != null){
			attachmentService.addFile(super.getUser(), AttachmentType.RENEW, file, entity.getId(), fileFileName);
		}
		return SHOW_MSG_PAGE;
	}
	
	@Action("preConfirmAccept")
	public String preConfirmAccept(){
		if(entity == null || entity.getId() == null){
			setSuccessPopMessage("缺少必要参数ID,请重新尝试");
			
			return SHOW_MSG_PAGE;
		}
		entity = certificateRenewService.find(entity.getId());
		attachs = attachmentService.findAll(entity.getId(), AttachmentType.RENEW);
		
		if(StringUtils.isBlank(this.getRedirectUrl())){
			if(flag != null && flag == 1){
				setRedirectUrl(getContextPath() + "/cm/index.do?currentPage=" + getCurrentPage(), "search", search);
			}else{
				setRedirectUrl("index.do?currentPage=" + getCurrentPage(), "search", search);
			}
		}

		return "confirmAccept";
	}
	
	@Action("confirmAccept")
	public String confirmAccept(){
		CertificateRenew certificateRenew = certificateRenewService.find(entity.getId());
		
		if(!CertificateRenewState.PASSED.equals(certificateRenew.getState())){
			this.addActionError("不能收证，申请单状态为:" + certificateRenew.getState());
			return preConfirmAccept();
		}
		if(this.validatorOutCertifications(certificateRenew.getOutCertifications()) || this.validatorInCertifications(certificateRenew.getInCertificateRenews())){
			return preConfirmAccept();
		}

		certificateRenewService.confirmAccept(super.getUser(), entity.getId());
		if(file != null){
			attachmentService.addFile(super.getUser(), AttachmentType.RENEW, file, entity.getId(), fileFileName);
		}
			
		setSuccessPopMessage("确认收证成功");
		return SHOW_MSG_PAGE;
	}
	
	public CertificateRenewService getCertificateRenewService() {
		return certificateRenewService;
	}

	public void setCertificateRenewService(
			CertificateRenewService certificateRenewService) {
		this.certificateRenewService = certificateRenewService;
	}

	public WorkflowService getWorkflowService() {
		return workflowService;
	}

	public void setWorkflowService(WorkflowService workflowService) {
		this.workflowService = workflowService;
	}

	public CertificateRenew getSearch() {
		return search;
	}

	public void setSearch(CertificateRenew search) {
		this.search = search;
	}

	public CertificateRenew getEntity() {
		return entity;
	}

	public void setEntity(CertificateRenew entity) {
		this.entity = entity;
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	public List<Attachment> getAttachs() {
		return attachs;
	}

	public void setAttachs(List<Attachment> attachs) {
		this.attachs = attachs;
	}

	public List<Brand> getBrands() {
		return brands;
	}

	public void setBrands(List<Brand> brands) {
		this.brands = brands;
	}

	public List<Financial> getFinancials() {
		return financials;
	}

	public void setFinancials(List<Financial> financials) {
		this.financials = financials;
	}

	public Workflow getWorkflow() {
		return workflow;
	}

	public void setWorkflow(Workflow workflow) {
		this.workflow = workflow;
	}

	public Integer getState() {
		return state;
	}

	public void setState(Integer state) {
		this.state = state;
	}

	public String getOperate() {
		return operate;
	}

	public void setOperate(String operate) {
		this.operate = operate;
	}

	public String getIds() {
		return ids;
	}

	public void setIds(String ids) {
		this.ids = ids;
	}

	public String getNames() {
		return names;
	}

	public void setNames(String names) {
		this.names = names;
	}

	public Integer getFlag() {
		return flag;
	}

	public void setFlag(Integer flag) {
		this.flag = flag;
	}

	public String getAuditMsg() {
		return auditMsg;
	}

	public void setAuditMsg(String auditMsg) {
		this.auditMsg = auditMsg;
	}

	public List<Shop> getShops() {
		return shops;
	}

	public void setShops(List<Shop> shops) {
		this.shops = shops;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
	
	
}
